# -*- coding: utf-8 -*-
"""
	From http://pyedpypers.org/index.php?page=project&projectid=11&view=true, but modified to scale and speed
image = image.resize( (self.sizex, image.size[1] * self.sizex / image.size[0] ), Image.NEAREST)      # use nearest neighbour
"""
import PIL.Image as Image
import pygame
from pygame.locals import *

import time

class GIFImage(object):
	"""
		This module is used for displaying gif images.
		filename: The filepath of the input image.
	"""
	def __init__(self, filename):
		self.filename = filename
		self.image = Image.open(filename)
		self.frames = []
		self.get_frames()

		self.cur = 0
		self.ptime = time.time()

		self.running = True
		self.breakpoint = len(self.frames)-1
		self.startpoint = 0
		self.reversed = False

	def get_frames(self):
		image = self.image

		pal = image.getpalette()
		base_palette = []
		for i in range(0, len(pal), 3):
			rgb = pal[i:i+3]
			base_palette.append(rgb)

		all_tiles = []
		try:
			while 1:
				if not image.tile:
					image.seek(0)
				if image.tile:
					all_tiles.append(image.tile[0][3][0])
				image.seek(image.tell()+1)
		except EOFError:
			image.seek(0)

		all_tiles = tuple(set(all_tiles))

		try:
			while 1:
				try:
					duration = image.info["duration"]
				except:
					duration = 100

				duration *= .001 #convert to milliseconds!
				cons = False

				x0, y0, x1, y1 = (0, 0) + image.size
				if image.tile:
					tile = image.tile
				else:
					image.seek(0)
					tile = image.tile
				if len(tile) > 0:
					x0, y0, x1, y1 = tile[0][1]

		##                    if tile[0][3][0] in (4, 5):
		##                        #replacement, don't have our own palette!
		##                        palette = base_palette
		##                    elif tile[0][3][0] in (6, 7):
		##                        #consecutive blitting, have own palette's
		##                        cons = True
		##                        pal = image.getpalette()
		##                        palette = []
		##                        for i in range(0, len(pal), 3):
		##                            rgb = pal[i:i+3]
		##                            palette.append(rgb)
		##                    else:
		##                        pal = image.getpalette()
		##                        palette = []
		##                        for i in range(0, len(pal), 3):
		##                            rgb = pal[i:i+3]
		##                            palette.append(rgb)
		##                else:
		##                    palette = base_palette

				if all_tiles:
					if all_tiles in ((6,), (7,)):
						cons = True
						pal = image.getpalette()
						palette = []
						for i in range(0, len(pal), 3):
							rgb = pal[i:i+3]
							palette.append(rgb)
					elif all_tiles in ((7, 8), (8, 7)):
						pal = image.getpalette()
						palette = []
						for i in range(0, len(pal), 3):
							rgb = pal[i:i+3]
							palette.append(rgb)
					else:
						palette = base_palette
				else:
					palette = base_palette

		##                try:
		##                    if image.dispose:
		##                        print "YAY!"
		##                        i = image.dispose
		##                        np = pygame.image.fromstring(i.tobytes(), i.size, i.mode)
		##                        np.set_palette(palette)
		##                        if "transparency" in i.info:
		##                            np.set_colorkey(i.info["transparency"])
		##                        cons = np
		##                    else:
		##                        print image.dispose
		##                except:
		##                    print image.dispose

				pi = pygame.image.fromstring(image.tobytes(), image.size, image.mode)
				pi.set_palette(palette)
				if "transparency" in image.info:
					pi.set_colorkey(image.info["transparency"])
				pi2 = pygame.Surface(image.size, SRCALPHA)
				if cons:
					for i in self.frames:
						pi2.blit(i[0], (0,0))
				pi2.blit(pi, (x0, y0), (x0, y0, x1-x0, y1-y0))

				self.frames.append([pi2, duration])
				image.seek(image.tell()+1)
		except EOFError:
			pass

	def render(self, screen, pos, size = None):
		if self.running:
			if time.time() - self.ptime > self.frames[self.cur][1]:
				if self.reversed:
					self.cur -= 1
					if self.cur < self.startpoint:
						self.cur = self.breakpoint
				else:
					self.cur += 1
					if self.cur >= self.breakpoint:
						self.cur = self.startpoint

				self.ptime = time.time()

		if size is not None:
			screen.blit(pygame.transform.scale(self.frames[self.cur][0], size), pos)
		else:
			screen.blit(self.frames[self.cur][0], pos)

	def seek(self, num):
		self.cur = num
		if self.cur < 0:
			self.cur = 0
		if self.cur >= len(self.frames):
			self.cur = len(self.frames)-1

	def set_bounds(self, start, end):
		if start < 0:
			start = 0
		if start >= len(self.frames):
			start = len(self.frames) - 1
		if end < 0:
			end = 0
		if end >= len(self.frames):
			end = len(self.frames) - 1
		if end < start:
			end = start
		self.startpoint = start
		self.breakpoint = end

	def pause(self):
		self.running = False

	def play(self):
		self.running = True

	def rewind(self):
		self.seek(0)
	def fastforward(self):
		self.seek(self.length()-1)

	def get_height(self):
		return self.image.size[1]
	def get_width(self):
		return self.image.size[0]
	def get_size(self):
		return self.image.size
	def length(self):
		return len(self.frames)
	def reverse(self):
		self.reversed = not self.reversed
	def reset(self):
		self.cur = 0
		self.ptime = time.time()
		self.reversed = False

	def copy(self):
		new = GIFImage(self.filename)
		new.running = self.running
		new.breakpoint = self.breakpoint
		new.startpoint = self.startpoint
		new.cur = self.cur
		new.ptime = self.ptime
		new.reversed = self.reversed
		return new

# def main():
# 	pygame.init()
# 	screen = pygame.display.set_mode((640, 480))

# 	hulk = GIFImage("hulk.gif")
# 	football = GIFImage("football.gif")
# 	hulk2 = hulk.copy()
# 	hulk2.reverse()
# 	hulk3 = hulk.copy()
# 	hulk3.set_bounds(0, 2)
# 	spiderman = GIFImage("spiderman7.gif")

# 	while 1:
# 		for event in pygame.event.get():
# 			if event.type == QUIT:
# 				pygame.quit()
# 				return

# 		screen.fill((255,255,255))
# 		hulk.render(screen, (50, 0))
# 		hulk2.render(screen, (50, 150))
# 		hulk3.render(screen, (50, 300))
# 		football.render(screen, (200, 50))
# 		spiderman.render(screen, (200, 150))
# 		pygame.display.flip()

# if __name__ == "__main__":
# 	main()
